#include "head.h"
//客户端
char* stdin_read(char* bufs, client_status* user) {
    //删除回车
    int len = strlen(bufs);
    len = len - 1;
    bufs[len] = '\0';
    //解剖 命令 空格切开
    char* savebuf = { 0 };
    char* token = strtok_r(bufs, " ", &savebuf);
    //printf("last :%s\n",savebuf);
    //保存当前路径
    strcpy(user->path, "/");
    //保存 后续切割路径
    strcpy(user->path_last, savebuf);

    return token;
}
bool get_filename(char* file_name, char* path, char path_cur[1000]) {
    // char path[] = "trgl/network-disk-simulation/my_project/serve";
    char* last_slash = strrchr(path_cur, '/');

    if (last_slash != NULL) {
        // 提取文件名
        strcpy(file_name, last_slash + 1);
        // file_name = last_slash + 1;

         // 提取前面的路径
        size_t path_len = last_slash - path_cur;
        // char dir_path[100];  // 确保这个大小足够存储路径
        strncpy(path, path_cur, path_len);
        path[path_len] = '\0';  // 确保字符串终止

        printf("文件名: %s\n", file_name);
        printf("路径: %s\n", path);
    }
    else {
        strcpy(file_name, path_cur);
        path[0] = '\0';
        // 没有找到斜杠，整个路径就是文件名
        printf("文件名: %s\n", path);
        printf("路径为空\n");
    }
    return true;

}

bool my_puts(sendMsg msg, client_status clients,int socket_fd){


    bzero(msg.msg,sizeof(msg.msg));
    //1、当前路径
    strcat(msg.msg,clients.path);
    printf("path1:%s\n",msg.msg);
//    strcat(msg.msg,clients.path_last);

  //  printf("path:%s\n",msg.msg);
    msg.mode=3;
  //  send(socket_fd,&msg,sizeof(msg),MSG_NOSIGNAL);
    //获取文件名
    char path_now[1000];
    strcpy(path_now,clients.path_last);
    //printf("path:%s\n",clients.path_last);
    char file_name[256];
    bzero(file_name,sizeof(file_name));
    char path[100];
    bzero(path,sizeof(path));
    char * result = strchr(path_now, '/');
    strcpy(file_name,path_now); 
    if(result!=NULL){
        get_filename(file_name,path,path_now);
        strcat(msg.msg,path);
     }
    
    printf("file_name:%s\n",file_name);
    send(socket_fd,&msg,sizeof(msg),MSG_NOSIGNAL);
    //2、要上传的路径
    int file_fd = open(file_name, O_RDWR);
   // ERROR_CHECK(file_fd,-1,"file_fd");
    
    if(file_fd==-1){
        printf("错误路径,本地找不到文件，请重新输入\n");
        return false;
    }

    struct stat st;
    fstat(file_fd, &st);
    //3、文件大小
    // sprintf(msg.msg + strlen(msg.msg), "%s%ld", "&file_size=", st.st_size);
    //4、 文件名长度+文件名
    // printf("msg:%s\n",msg.msg);
    //   int file_len = strlen(file_name);                                
    //   sprintf(msg.msg + strlen(msg.msg), "%s%d", "&file_len=", file_len);

    //  strcat(msg.msg,"&file_name=");
    // strcat(msg.msg,file_name);



    // printf("msg:%s\n",msg.msg);

    int ret_send =send(socket_fd, &st.st_size, sizeof(off_t), MSG_NOSIGNAL);

    ERROR_CHECK(ret_send,-1,"ret_send");

    int len = strlen(file_name);
    // 先写给客户端: int类型的文件名的长度    文件名
    int len_ret= send(socket_fd, &len, sizeof(int), 0);
    ERROR_CHECK(len_ret,-1,"len_ret"); 
    int name_ret=send(socket_fd, file_name, len, 0);
    ERROR_CHECK(name_ret,-1,"name_ret");

    // 接收服务器已接收的文件大小
    off_t received_size;
    int ret = recv(socket_fd, &received_size, sizeof(off_t), MSG_WAITALL);
    ERROR_CHECK(ret, -1, "recv received_size");
    printf("服务器已接收大小: %ld\n", received_size);
    
    //如果 偏移量是和文件大小一样就退出 并且告诉用户已经有
    //还不够健全 应该是核实对方的hash值 才知道是不是已经存在
    //TODO
    if(received_size==st.st_size){
        printf("文件已经存在，禁止重复上传\n");
        return false;
    }

    // 使用 sendfile 从偏移量继续发送文件内容
    off_t offset = received_size;
    ssize_t sent_bytes;
    while (offset < st.st_size) {
        sent_bytes = sendfile(socket_fd, file_fd, &offset, st.st_size - offset);
        if (sent_bytes <= 0) {
            if (errno == EINTR || errno == EAGAIN) {
                continue; // 如果发生了中断或资源临时不可用，继续发送
            } else {
                perror("sendfile");
                close(file_fd);
                return false;
            }
        }
        printf("sent_bytes:%ld\n",sent_bytes);
        offset += sent_bytes;
    }

    // 零拷贝

    close(file_fd);
    return true;

}


